#include "mongraph.h"
#include <iostream>
#include <QWidget>
#include <QSize>
#include <vector>

using namespace std;

MonGraph::MonGraph(){
    this->step = 0;
    this->nextStep();
}
QRectF MonGraph::boundingRect() const{
    qreal penWidth = 1;
    return QRectF(penWidth / 2,penWidth / 2,penWidth,penWidth);
}
void MonGraph::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    vector<Link*> links = this->gr.getLinks();
    vector<Link*>::iterator currentL;
    vector<Point*> points = this->gr.getPoints();
    vector<Point*>::iterator currentP;
    vector<vector<Point*> > obstacles = this->gr.getObstacles();
    vector<vector<Point*> >::iterator currentO;
    vector<Link*> chemin;
    Point* max;
    QSize tmp;
    tmp = widget->frameSize();

    currentP = points.begin();
        if(currentP != points.end()){
        max = *currentP;
        while(currentP != points.end()){
            if(max->getX()<(*currentP)->getX() && max->getY()<(*currentP)->getY()){
                max = *currentP;
            }
            currentP++;
        }
        this->dx = -(tmp.width()/2)+10;
        this->dy = (tmp.height()/2)-10;
        if(tmp.height()/tmp.width() < max->getY()/max->getX()){
            this->ry = (tmp.height()-20)/max->getY();
            this->rx = this->ry*(tmp.width()/tmp.height());
            this->ry = -this->ry;
        }
        else{
            this->rx = (tmp.width()-20)/max->getX();
            this->ry = -(this->rx*(tmp.height()/tmp.width()));
        }
    }

    //Affichage des obstacles
    currentO = obstacles.begin();
    while(currentO != obstacles.end()){
        int i;
        QPoint* points = new QPoint[currentO->size()];
        currentP = currentO->begin();
        i = 0;
        while(currentP != currentO->end()){
            points[i].setX(this->dx+(this->rx*(*currentP)->getX()));
            points[i].setY(this->dy+(this->ry*(*currentP)->getY()));
            currentP++;
            i++;
        }
        painter->setBrush(Qt::red);
        painter->setPen(Qt::red);
        painter->drawPolygon(points,i,Qt::WindingFill);
        delete [] points;
        currentO++;
    }

    //Affichage du chemin le plus cours
    chemin = this->gr.getGraph()->astar(this->debut,this->fin);
    currentL = chemin.begin();
    while(currentL != chemin.end()){
        this->paintLink(*currentL,painter,true);
        currentL++;
    }

    //Affichage des points
    currentP = points.begin();
    while(currentP != points.end()){
        this->paintPoint((*currentP),painter);
        currentP++;
    }

    //Affichages des liens
    currentL = links.begin();
    while(currentL != links.end()){
        this->paintLink((*currentL),painter);
        currentL++;
    }
}
void MonGraph::nextStep(){
    vector<Point*> obstacle;
    Point* p[10];
    switch(this->step){
    case 0:
        this->debut = this->gr.createPoint(0,0);
        this->fin = this->gr.createPoint(15,15);
        break;
    case 1:
        p[0] = new Point(1,3);
        p[1] = new Point(1,6);
        p[2] = new Point(4,6);
        p[3] = new Point(4,3);
        obstacle.push_back(p[0]);
        obstacle.push_back(p[1]);
        obstacle.push_back(p[2]);
        obstacle.push_back(p[3]);
        this->gr.createObstacle(obstacle);
        break;
    case 2:
        p[0] = new Point(6,7);
        p[1] = new Point(6,11);
        p[2] = new Point(9,11);
        p[3] = new Point(9,7);
        obstacle.push_back(p[0]);
        obstacle.push_back(p[1]);
        obstacle.push_back(p[2]);
        obstacle.push_back(p[3]);
        this->gr.createObstacle(obstacle);
        break;
    case 3:
        obstacle = this->gr.getObstacles()[0];
        obstacle[0]->setY((obstacle[0]->getY())-1);
        obstacle[1]->setY((obstacle[1]->getY())-1);
        obstacle[2]->setY((obstacle[2]->getY())-1);
        obstacle[3]->setY((obstacle[3]->getY())-1);
        break;
    case 4:
        obstacle = this->gr.getObstacles()[1];
        obstacle[0]->setX((obstacle[0]->getX())+2);
        obstacle[0]->setY((obstacle[0]->getY())-2);
        obstacle[1]->setX((obstacle[1]->getX())+2);
        obstacle[1]->setY((obstacle[1]->getY())-2);
        obstacle[2]->setX((obstacle[2]->getX())+2);
        obstacle[2]->setY((obstacle[2]->getY())-2);
        obstacle[3]->setX((obstacle[3]->getX())+2);
        obstacle[3]->setY((obstacle[3]->getY())-2);
        break;
    }
    cout << this->gr << endl;
    this->step++;
}
void MonGraph::paintPoint(Point* p, QPainter* painter){
    painter->setBrush(Qt::green);
    painter->setPen(Qt::green);

    painter->drawArc(this->dx+(this->rx*p->getX()-3),this->dy+(this->ry*p->getY()-3),6,6,0,360*16);
}
void MonGraph::paintLink(Link* l, QPainter* painter,bool chemin){
    if(chemin){
        QPen tmp;
        tmp.setColor(Qt::blue);
        tmp.setWidth(4);
        painter->setPen(tmp);
    }
    else{
        painter->setPen(Qt::black);
    }
    painter->drawLine(this->dx+(this->rx*l->getP1()->getX()),this->dy+(this->ry*l->getP1()->getY()),this->dx+(this->rx*l->getP2()->getX()),this->dy+(this->ry*l->getP2()->getY()));
}

